
#include <stdio.h>
#include <stdlib.h>

#include "imageppm.h"

void load_ppm_binary(FILE *f, Image *img);
void load_ppm_text(FILE *f, Image* img);

void release_image(Image *img)
{
	if (img == NULL)
		return;

    free(img->r);
    free(img->g);
    free(img->b);
    free(img);
}

void* getImageChannel(Image *img, int rgb)
{
    switch (rgb){
        case COLOR_RED:
            return img->r;
        case COLOR_GREEN:
            return img->g;
        case COLOR_BLUE:
            return img->b;
    }

    return NULL;
}

Image* load_image(const char* file){

    char M1, M2;
    int width, height, maxColor;
    Image* img = NULL;
    FILE *f = fopen(file, "rb");

	if (f == NULL)
		return NULL;

    // Read "Magic Number"
    fscanf(f, "%c%c ", &M1, &M2);

    if (M1 != 'P')
        return NULL;

    // NAO TRATA COMENTARIOS

    // Read dimensions
    fscanf(f, "%d %d %d%*c", &width, &height, &maxColor);

    img = (Image*) malloc(sizeof(Image));
    img->width = width;
    img->height = height;

    // printf("%c%c Image size: %d %d, %d\n", M1,M2, width, height, maxColor);

    if (maxColor < 256){ // 1 byte color
        img->colorsize = 1;
    }else{ // 2 byte color
        img->colorsize = 2;
    }

    if (M2 == '6'){ // Binary
        load_ppm_binary(f, img);
    }else if (M2 == '3') { // Text
        load_ppm_text(f, img);
    }

    fclose(f);

	return img;
}

void load_ppm_binary(FILE *f, Image *img){

    int i, j;

    img->r = calloc(img->width*img->height,img->colorsize);
    img->g = calloc(img->width*img->height,img->colorsize);
    img->b = calloc(img->width*img->height,img->colorsize);

    unsigned char* ptrR = (unsigned char*) img->r;
    unsigned char* ptrG = (unsigned char*) img->g;
    unsigned char* ptrB = (unsigned char*) img->b;

    for (i = 0; i < img->height; ++i){
        for (j = 0; j < img->width; ++j){
            int addr = (j + i*img->width )*img->colorsize;
            fread( &(ptrR[addr]), img->colorsize, 1, f );
            fread( &(ptrG[addr]), img->colorsize, 1, f );
            fread( &(ptrB[addr]), img->colorsize, 1, f );
        }
    }
}

void load_ppm_text(FILE *f, Image* img){

    int i, j;
    int r, g, b;
	img->r = calloc(img->width*img->height,img->colorsize);
    img->g = calloc(img->width*img->height,img->colorsize);
    img->b = calloc(img->width*img->height,img->colorsize);

    if (img->colorsize == 1){ // 1 byte color
        for (i = 0; i < img->height; ++i){
            for (j = 0; j < img->width; ++j){
                fscanf(f, "%d %d %d", &r, &g, &b);
                ((unsigned short*) img->r)[j + i*img->width] = r;
                ((unsigned short*) img->g)[j + i*img->width] = g;
                ((unsigned short*) img->b)[j + i*img->width] = b;
            }
        }

    }else{ // 2 byte color
        for (i = 0; i < img->height; ++i){
            for (j = 0; j < img->width; ++j){
                fscanf(f, "%d %d %d", &r, &g, &b);
                ((unsigned short*) img->r)[j + i*img->width] = r;
                ((unsigned short*) img->g)[j + i*img->width] = g;
                ((unsigned short*) img->b)[j + i*img->width] = b;
            }
        }
    }
}


void save_image(Image *img, const char* file, int mode)
{
	int i;
	FILE *f;

	if (img == NULL)
		return;

	// printf("img: %d %d\n", img->width, img->height);

	if (mode == SAVE_MODE_TEXT)
    {
		f = fopen(file, "w");
		if (f == NULL){
            printf("Could not open file for writing! %s\n", file);
            return;
		}

		fprintf(f,"P3 %d %d %d ", img->width, img->height, (img->colorsize<256)?255:65535);

		if (img->colorsize == 1) // 1 byte color
		{
			for (i=0; i < img->width * img->height; ++i){
				fprintf(f, "%d %d %d ", ((unsigned char*)img->r)[i], ((unsigned char*)img->g)[i], ((unsigned char*)img->b)[i]);
			}
		} else { // 2 byte color
			for (i=0; i < img->width * img->height; ++i){
				fprintf(f, "%d %d %d ", ((unsigned short*)img->r)[i], ((unsigned short*)img->g)[i], ((unsigned short*)img->b)[i]);
			}
		}
	}
	else if (mode == SAVE_MODE_BINARY)
	{
		f = fopen(file, "wb");
		if (f == NULL){
            printf("Could not open file for writing! %s\n", file);
            return;
		}

		fprintf(f,"P6 %d %d %d ", img->width, img->height, (img->colorsize<256)?255:65535);

        for (i=0; i < img->width * img->height; ++i){
            fwrite(&((unsigned char*)img->r)[i*img->colorsize], img->colorsize, 1, f );
            fwrite(&((unsigned char*)img->g)[i*img->colorsize], img->colorsize, 1, f );
            fwrite(&((unsigned char*)img->b)[i*img->colorsize], img->colorsize, 1, f );
        }
	} else {
        return;
	}

	fclose(f);
}
